/*
 * Headers for Winbond USB2WLAN b/g WiFi device driver on Linux 2.6
 * Many portions based on original GPLed driver from Winbond.
 *
 * Written by Ferenc Csicsova & Karoly Kasza
 * Based on RTL8187 driver in kernel.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

//EEPROM DATA
#define EEPROM_MAC	0x00
#define EEPROM_RFCHIP	0x0d
#define EEPROM_TXVGA	0x10
#define EEPROM_SC_INT	0x1d
#define EEPROM_VCO_TRIM	0x20
#define EEPROM_ANT	0x21	//Antenna on/off?
#define EEPROM_TEXT	0x22	//text

//configure_filter options
#define WBUSB_RX_CONF_MULTICAST 0x01000000	//Enable multicast

//HW registers
#define REG_U		0x0200
#define REG_EEPROM	0x03b4		//EEPROM register
#define REG_D		0x0400
#define REG_M		0x0800
#define REG_BB		0x1000

#define DEBUG(x...) { }
#define DEBUG_REG(x...) { }
#define DEBUG_VM0(x...) { }
#define DEBUG_RX(x...) { }

//Debug code - general
#ifdef DEBUG1
#warning General DEBUG code turned on
#undef DEBUG
#define DEBUG(x...) { printk("wbusb: [debug] "); printk(x); printk("\n"); }
#endif

//Debug code - register management
#ifdef DEBUG2
#warning Register DEBUG code turned on
#undef DEBUG_REG
#define DEBUG_REG(x...) { printk("wbusb: [debug-REG] "); printk(x); printk("\n"); }
#endif

//Debug code - VM0 management
#ifdef DEBUG3
#warning VM0 DEBUG code turned on
#undef DEBUG_VM0
#define DEBUG_VM0(x...) { printk("wbusb: [debug-VM0] "); printk(x); printk("\n"); }
#endif

//Debug code - RX management
#ifdef DEBUG4
#warning RX DEBUG code turned on
#undef DEBUG_RX
#define DEBUG_RX(x...) { printk("wbusb: [debug-RX] "); printk(x); printk("\n"); }
#endif

//Maximum RX bytes (4096)
#define WBUSB_MAX_RX 0x1000

#define SCAN_MAX_CH_TIME 5

//-------- FROM OLD DRIVER - Mxx register default values

#define DEFAULT_CWMIN			31	//(M2C) CWmin. Its value is in the range 0-31.
#define DEFAULT_CWMAX			1023	//(M2C) CWmax. Its value is in the range 0-1023.
#define DEFAULT_AID			1	//(M34) AID. Its value is in the range 1-2007.
#define DEFAULT_RATE_RETRY_LIMIT	2	//(M38) as named
#define DEFAULT_LONG_RETRY_LIMIT	7	//(M38) LongRetryLimit. Its value is in the range 0-15.
#define DEFAULT_SHORT_RETRY_LIMIT	7	//(M38) ShortRetryLimit. Its value is in the range 0-15.
#define DEFAULT_PIFST			25	//(M3C) PIFS Time. Its value is in the range 0-65535.
#define DEFAULT_EIFST			354	//(M3C) EIFS Time. Its value is in the range 0-1048575.
#define DEFAULT_DIFST			45	//(M3C) DIFS Time. Its value is in the range 0-65535.
#define DEFAULT_SIFST			5	//(M3C) SIFS Time. Its value is in the range 0-65535.
#define DEFAULT_OSIFST			10	//(M3C) Original SIFS Time. Its value is in the range 0-15.
#define DEFAULT_ATIMWD			0	//(M40) ATIM Window. Its value is in the range 0-65535.
#define DEFAULT_SLOT_TIME		20	//(M40) ($) SlotTime. Its value is in the range 0-255.
#define DEFAULT_MAX_TX_MSDU_LIFE_TIME	512	//(M44) MaxTxMSDULifeTime. Its value is in the range 0-4294967295.
#define DEFAULT_BEACON_INTERVAL		500	//(M48) Beacon Interval. Its value is in the range 0-65535.
#define DEFAULT_PROBE_DELAY_TIME	200	//(M48) Probe Delay Time. Its value is in the range 0-65535.
#define DEFAULT_PROTOCOL_VERSION	0	//(M4C)
#define DEFAULT_MAC_POWER_STATE		2	//(M4C) 2: MAC at power active
#define DEFAULT_DTIM_ALERT_TIME		0

//--------

//Sleep, taken from old driver
#define OS_SLEEP( _MT )	{ set_current_state(TASK_INTERRUPTIBLE); \
			  schedule_timeout( _MT*HZ/1000000 ); }

//Decide for fill_control_urb if it is coming or going
//Used with struct _REG_QUEUE
#define REG_DIRECTION(_x,_y)   ((_y)->DIRECT ==0 ? usb_rcvctrlpipe(_x,0) : usb_sndctrlpipe(_x,0))

//Needed for bitreverse
#define     GetBit( dwData, i)      ( dwData & (0x00000001 << i)) 
#define     SetBit( dwData, i)      ( dwData | (0x00000001 << i))
#define     ClearBit( dwData, i)    ( dwData & ~(0x00000001 << i))

//AutoIncrement flag for burstwrite - sent to hardware...
#define AUTO_INC 0
#define NO_INC 1

//Buffer for MAX_USB_RX
#define MAX_USB_RX_BUFF_NO 8
#define MAX_USB_RX_BUFF_SIZE 4096

// For VM state (i.e. EP0vm_state value)
enum {
	VM_STOP = 0,
	VM_RUNNING,
	VM_COMPLETED
};

//Old code!!!
typedef struct _REG_QUEUE {
	struct	urb *purb;
	void*	pUsbReq;
	void*	Next;
	union {
		u32	VALUE;
		u32*	pBuffer;
	};
	u8	RESERVED[4];	// space reserved for communication
	u16	INDEX;		// For storing the register index
	u8	RESERVED_VALID;	// Indicate whether the RESERVED space is valid at this command.
	u8	DIRECT;		// 0:In 1:Out
	
} REG_QUEUE, *PREG_QUEUE;

//Forward definition for rfchip
struct wbusb_priv;

struct registers {
	u32 U1B0;	//hw radio on/off
	u32 U1BC;	//LED
	u32 D00;	//DMA Control
	u32 M00;
	union {
		struct {
			u32 M04;
			u32 M08;
		};
		u8 mcast[8];
	};
	u32 M24;
	u32 M28;
	u32 M2C;
	u32 M38;
	u32 M3C;
	u32 M40;
	u32 M44;
	u32 M48;
	u32 M4C;
	u32 M60;
	u32 M68;
	u32 M70;
	u32 M74;
	u32 M78;	//ERP information
	u32 M7C;
	u32 M80;
	u32 M84;
	u32 M88;
	u32 M98;

	u32 BB0C;	// Used for LNA calculation
	u32 BB2C;
	u32 BB30;	//11b acquisition control register
	u32 BB3C;
	u32 BB48;	// 20051221.1.a 20060613.1 Fix OBW issue of 11b/11g rate
	u32 BB4C;	// 20060613.1  Fix OBW issue of 11b/11g rate
	u32 BB50;	//mode control register
	u32 BB54;
	u32 BB58;	//IQ_ALPHA
	u32 BB5C;	// For test
	u32 BB60;	// for WTO read value
	
	u8 sync_io;	//sync operation
	u8 EP0vm_state; //Operation running
	u32 EP0vm_count; //How many times to run
	spinlock_t spinlock;

	//From ooold code
	PREG_QUEUE pRegFirst;
	PREG_QUEUE pRegLast;
};

//Radio chip
struct rfchip {
	u8 type;
	char *name;
	int (*start)(struct wbusb_priv *priv);
	int (*rf_synt_init)(struct wbusb_priv *priv);
	int (*bb_proc_init)(struct wbusb_priv *priv);
};

//RX structure
struct wbusb_rx_struct {
	u32 bytes_rec;
	u32 rx_count;
	/* This is a FIX 32K allocated memory for 8 incoming packets
	 * Could be made with dynamic pointers, but then it would eat CPU
	 * to kmalloc everytime...
	 * Also, it is dividable with 4 anytime (XOR 0x03)
	 */
//May BE or NOT BE needed :) probably not
//	struct _buffer {
//		u8 data[ ((MAX_USB_RX_BUFF_SIZE+3) & ~0x03) ];
		u16 size;
//	} buffer[MAX_USB_RX_BUFF_NO];
	u8 EP3vm_state;
	u8 buffer_id;
	struct urb *rx_urb;
	u8 *pdrx;
};

//Device
struct wbusb_priv {
	struct	ieee80211_channel channels[14];
	struct	ieee80211_rate rates[12];
	struct	ieee80211_supported_band band;
	struct	ieee80211_vif *vif;
	struct	usb_device *udev;
	int	mode;
	struct	sk_buff_head rx_queue;
	struct	registers regs;
	struct	rfchip radio;
	u8	vco_trim;
	u8	tx_vga;
	u16	sw_ant_set;
	u8	region;
	u16	scan_int;
	u8	bssid[8]; //should be 6...
	u8	cwmin;
	u16	cwmax;
	u16	aid;
	u8	slot_time_select; //9 or 20
	u16	beacon_period;
	u16	probe_delay;
	union {
		struct {
			u32 perm_addr_high;
			u32 perm_addr_low;
		};
		u8 perm_addr[ETH_ALEN];
	};
	struct wbusb_rx_struct rx;
};

/*
//For wbusb_rx_cb
struct wbusb_rx_info {
	struct urb *urb;
	struct ieee80211_hw *dev;
};
*/

//Packet header
//TO CHECK,MAY NOT BE PROPER
struct wbusb_rx_hdr {
	__le32 flags;
	u8 noise;
	u8 signal;
	u8 agc;
	u8 reserved;
	__le64 mac_time;
} __attribute__((packed));

//TO BE CHECKED
static const struct ieee80211_channel wbusb_channels[] = {
	{ .center_freq = 2412 },
	{ .center_freq = 2417 },
	{ .center_freq = 2422 },
	{ .center_freq = 2427 },
	{ .center_freq = 2432 },
	{ .center_freq = 2437 },
	{ .center_freq = 2442 },
	{ .center_freq = 2447 },
	{ .center_freq = 2452 },
	{ .center_freq = 2457 },
	{ .center_freq = 2462 },
	{ .center_freq = 2467 },
	{ .center_freq = 2472 },
	{ .center_freq = 2484 },
};

//TO BE CHECKED
static const struct ieee80211_rate wbusb_rates[] = {
	{ .bitrate = 10, .hw_value = 0, },
	{ .bitrate = 20, .hw_value = 1, },
	{ .bitrate = 55, .hw_value = 2, },
	{ .bitrate = 110, .hw_value = 3, },
	{ .bitrate = 60, .hw_value = 4, },
	{ .bitrate = 90, .hw_value = 5, },
	{ .bitrate = 120, .hw_value = 6, },
	{ .bitrate = 180, .hw_value = 7, },
	{ .bitrate = 240, .hw_value = 8, },
	{ .bitrate = 360, .hw_value = 9, },
	{ .bitrate = 480, .hw_value = 10, },
	{ .bitrate = 540, .hw_value = 11, },
};

//Some public functions, so RF functions can use them

int wbusb_reg_read(struct wbusb_priv *priv, u16 reg, u32 *regval);
int wbusb_reg_read_sync(struct wbusb_priv *priv, u16 reg, u32 *regval);
int wbusb_reg_write_sync(struct wbusb_priv *priv, u16 reg, u32 regval);
int wbusb_reg_write(struct wbusb_priv *priv, u16 reg, u32 regval);
int wbusb_reg_write_wcbv(struct wbusb_priv *priv, u16 reg, u32 regval, s8 *pval, s8 len);
int wbusb_reg_write_burst(struct wbusb_priv *priv, u16 reg, u32 *pregdata, u8 numdata, u8 flag);

//RX functions for DEV
u8 wbusb_rx_init(struct wbusb_priv *priv);
void wbusb_rx_start(struct wbusb_priv *priv);

u32 BitReverse( u32 dwData, u32 DataLength);
